package com.monas.client.view;

import java.util.List;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.forms.widgets.Section;

import com.monas.client.AbstractMonasViewPart;
import com.monas.client.Activator;
import com.monas.client.Constants;
import com.monas.client.database.MonasResourceDatabase;
import com.monas.client.dialog.AddNodeDialog;
import com.monas.client.dialog.AddUserDialog;
import com.monas.client.dialog.EditNodeDialog;
import com.monas.client.dialog.EditUserDialog;
import com.monas.client.util.Node;
import com.monas.client.util.UIHelper;

public class AdministrationView extends AbstractMonasViewPart {

	public static final String ID = "com.monas.client.view.AdministrationView";

	private static final int USER_INDEX = 1;

	private static final int REMARK_INDEX = 5;

	private static final int NODE_INDEX = 1;

	private SashForm vertical;

	private Table userTable;

	private Table nodeTable;

	@Override
	public void createPartControl(Composite parent) {
		createForm(parent, "ADMINISTRATION");

		Composite client = toolkit.createComposite(form.getBody(), SWT.WRAP);
		client.setLayout(new FillLayout());

		vertical = new SashForm(client, SWT.VERTICAL);
		createUserAdministration();
		createNodeAdministration();

		vertical.setWeights(new int[] { 1, 1 });
	}

	private void createNodeAdministration() {
		Section nodeSection = createSection(vertical, "Node Administration");
		Composite composite = toolkit.createComposite(nodeSection, SWT.BORDER);
		composite.setLayout(new GridLayout(1, false));
		createNodeToolbar(composite);
		nodeTable = createTable(composite);
		createNodeColumns();
		createNodeContents();
		nodeSection.setClient(composite);
	}

	private void createNodeContents() {
		try {
			MonasResourceDatabase source = MonasResourceDatabase.getInstance();
			createItems(nodeTable, source.getNodes());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void createNodeColumns() {
		createColumn(nodeTable, Constants.NO, 40);
		createColumn(nodeTable, "Node", 150);
		createColumn(nodeTable, "Operating System", 150);
		createColumn(nodeTable, "Host", 120);
		createColumn(nodeTable, "Username", 150);
		createColumn(nodeTable, "Password", 150);
		createColumn(nodeTable, "Ending Key", 100);
		createColumn(nodeTable, "Status", 100);
	}

	private void createNodeToolbar(final Composite parent) {
		Composite toolbar = createToolbar(parent);

		Button add = createButton(toolbar, Constants.ADD_NODE,
				Constants.IMAGE_NODE_ADD);
		add.setToolTipText("Add node for monitoring");
		add.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent event) {
				AddNodeDialog dialog = new AddNodeDialog(parent.getShell());
				if (dialog.open() == AddNodeDialog.OK) {
					Node node = dialog.getNode();

					try {
						MonasResourceDatabase source = MonasResourceDatabase
								.getInstance();
						source.addNode(node);
					} catch (Exception e) {
						e.printStackTrace();
					}
					refresh();
				}
			}
		});

		Button edit = createButton(toolbar, Constants.EDIT_NODE,
				Constants.IMAGE_NODE_EDIT);
		edit.setToolTipText("Edit node to change configuration");
		edit.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent event) {
				TableItem[] items = nodeTable.getSelection();
				Shell shell = parent.getShell();
				if (!checkItems(items, shell, Constants.EDIT_NODE, "node")) {
					return;
				}

				TableItem item = items[0];
				Node node = new Node();
				node.setNode(item.getText(1));
				node.setOs(item.getText(2));
				node.setHost(item.getText(3));
				node.setUsername(item.getText(4));
				node.setPassword(item.getText(5));
				node.setEndLine(item.getText(6));

				EditNodeDialog dialog = new EditNodeDialog(shell, node);
				if (dialog.open() == EditNodeDialog.OK) {
					Node newNode = dialog.getNode();

					try {
						MonasResourceDatabase source = MonasResourceDatabase
								.getInstance();
						source.editNode(newNode);
					} catch (Exception e) {
						e.printStackTrace();
					}
					refresh();
				}
			}

		});

		Button delete = createButton(toolbar, Constants.DELETE_NODE,
				Constants.IMAGE_NODE_DELETE);
		delete.setToolTipText("Delete node to stop monitoring");
		delete.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent event) {
				TableItem[] items = nodeTable.getSelection();
				Shell shell = parent.getShell();
				if (!checkItems(items, shell, Constants.DELETE_NODE, "node")) {
					return;
				}

				TableItem item = items[0];

				if (MessageDialog.openConfirm(shell, Constants.DELETE_NODE,
						"Are you sure want to delete this node?")) {
					try {
						MonasResourceDatabase source = MonasResourceDatabase
								.getInstance();
						source.deleteNode(item.getText(NODE_INDEX));
					} catch (Exception e) {
						e.printStackTrace();
					}

					refresh();
				}
			}
		});
	}

	private void createUserAdministration() {
		Section userSection = createSection(vertical, "User Administration");
		Composite composite = toolkit.createComposite(userSection, SWT.BORDER);
		composite.setLayout(new GridLayout(1, false));
		createUserToolbar(composite);
		userTable = createTable(composite);
		createUserColumns();
		createUserContents();
		userSection.setClient(composite);
	}

	private Table createTable(Composite parent) {
		Table table = toolkit.createTable(parent, SWT.VIRTUAL | SWT.MULTI
				| SWT.V_SCROLL | SWT.FULL_SELECTION);
		table.setLayoutData(UIHelper.fillBoth());
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		return table;
	}

	private void createUserToolbar(final Composite parent) {
		Composite toolbar = createToolbar(parent);

		Button add = createButton(toolbar, Constants.ADD_USER,
				Constants.IMAGE_USER_ADD);
		add.setToolTipText("Create new user for access application");
		add.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				AddUserDialog dialog = new AddUserDialog(parent.getShell());
				if (dialog.open() == AddUserDialog.OK) {
					String username = dialog.getUsername();
					String password = dialog.getPassword();
					boolean isAdmin = dialog.isAdmin();
					String remark = dialog.getRemark();
					try {
						MonasResourceDatabase source = MonasResourceDatabase
								.getInstance();
						source.addUser(username, password, isAdmin, remark);
					} catch (Exception e) {
						e.printStackTrace();
					}
					refresh();
				}
			}
		});

		Button edit = createButton(toolbar, Constants.EDIT_USER,
				Constants.IMAGE_USER_EDIT);
		edit.setToolTipText("Edit user for change username, password, or remark");
		edit.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				TableItem[] items = userTable.getSelection();
				Shell shell = parent.getShell();
				if (!checkItems(items, shell, Constants.EDIT_USER, "user")) {
					return;
				}

				TableItem item = items[0];
				EditUserDialog dialog = new EditUserDialog(shell, item
						.getText(USER_INDEX), item.getText(REMARK_INDEX));
				if (dialog.open() == EditUserDialog.OK) {
					String username = dialog.getUsername();
					String password = dialog.getPassword();
					String remark = dialog.getRemark();

					try {
						MonasResourceDatabase source = MonasResourceDatabase
								.getInstance();
						source.editUser(username, password, remark);
					} catch (Exception e) {
						e.printStackTrace();
					}

					refresh();
				}
			}
		});

		Button delete = createButton(toolbar, Constants.DELETE_USER,
				Constants.IMAGE_USER_DELETE);
		delete.setToolTipText("Delete user from selection in table");
		delete.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent event) {
				TableItem[] items = userTable.getSelection();
				Shell shell = parent.getShell();
				if (!checkItems(items, shell, Constants.DELETE_USER, "user")) {
					return;
				}

				TableItem item = items[0];

				if (MessageDialog.openConfirm(shell, Constants.DELETE_USER,
						"Are you sure want to delete this user?")) {
					try {
						MonasResourceDatabase source = MonasResourceDatabase
								.getInstance();
						source.deleteUser(item.getText(USER_INDEX));
					} catch (Exception e) {
						e.printStackTrace();
					}

					refresh();
				}
			}
		});
	}

	private Composite createToolbar(final Composite parent) {
		Composite toolbar = toolkit.createComposite(parent);
		toolbar.setLayoutData(UIHelper.fillHorizontal());
		toolbar.setLayout(new RowLayout());
		return toolbar;
	}

	private boolean checkItems(TableItem[] items, Shell shell, String title,
			String label) {
		String message = "Please select " + label + " in table!";
		if (items == null) {
			MessageDialog.openInformation(shell, title, message);
			return false;
		}

		if (items.length == 0) {
			MessageDialog.openInformation(shell, title, message);
			return false;
		}
		return true;
	}

	private Button createButton(Composite parent, String text, String pathImage) {
		Button button = toolkit.createButton(parent, text, SWT.PUSH);
		if (pathImage != null) {
			button.setImage(Activator.getImage(pathImage));
		}
		return button;
	}

	private void createUserColumns() {
		createColumn(userTable, Constants.NO, 40);
		createColumn(userTable, "Username", 200);
		createColumn(userTable, "Password", 200);
		createColumn(userTable, "User Type", 100);
		createColumn(userTable, "Status", 100);
		createColumn(userTable, "Remark", 300);
	}

	private void createUserContents() {
		try {
			MonasResourceDatabase source = MonasResourceDatabase.getInstance();
			createItems(userTable, source.getAllUser());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void createItems(Table table, List<Object[]> list) {
		Integer no = 1;
		for (Object[] values : list) {
			String[] fields = new String[values.length + 1];
			for (int i = 0; i < fields.length; i++) {
				if (i == 0) {
					fields[0] = no.toString();
				} else {
					fields[i] = (String) values[i - 1];
				}
			}

			TableItem item = new TableItem(table, SWT.None);
			item.setText(fields);

			no++;
		}
	}

	@Override
	public Image getViewImage() {
		return Activator.getImage(Constants.IMAGE_ADMIN);
	}

	@Override
	public void refresh() {
		userTable.removeAll();
		createUserContents();
		userTable.layout();

		nodeTable.removeAll();
		createNodeContents();
		nodeTable.layout();
	}

}
